package controller;

import handlers.NPCInteractionHandler;
import interaction.InteractionCommand;
import interaction.InteractionOption;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import model.InteractionManager;
import model.Observer;
import model.Subject;
import pausing.Pauser;
import view.overlay.InteractionOverlay;

public class NPCInteractionController extends Controller implements Observer {
	
	private InteractionManager mManager;
	private NPCInteractionHandler mCurHandler;
	
	private InteractionOverlay mOverlay;
	
	public NPCInteractionController(InteractionOverlay io) {
		
		// Obtain and register to the InteracctionManager to determine if we
		// have an interaction in the future
		mManager = InteractionManager.getInstance();
		mManager.register(this);
		
		mOverlay = io;
	}

	@Override
	public List<GameControl> getKeyControls() {
		List<GameControl> ctrls = new ArrayList<GameControl>();
		
		ctrls.add(new GameControl(KeyEvent.VK_F8, "CHEAT_START_INTERACTION", "Start Interaction") {

			@Override
			protected void execute() {
				forceStartInteraction();
				
			}
			
		});
		
		ctrls.add(new GameControl(KeyEvent.VK_F9, "CHEAT_EXIT_INTERACTION", "Exit Interaction") {

			@Override
			protected void execute() {
				forceStopInteraction();
				
			}
			
		});
		
		return (ctrls);
	}

	@Override
	public void update(Subject sourceSubject) {
		if (sourceSubject.equals(mManager)) {
			// Received event notification from the manager
			mCurHandler = mManager.getHandler();
			if (mCurHandler != null) {
				startInteraction();
			}
		}
	}
	
	private void startInteraction() {
		// Don't process on no handler
		if (mCurHandler == null) return;
		
		InteractionOption iopt = mCurHandler.getCommands();
		Iterator<InteractionCommand> it = iopt.iterator();
		
		Map<InteractionCommand, MouseListener> options = new LinkedHashMap<InteractionCommand, MouseListener>();
		
		while (it.hasNext()) {
			final InteractionCommand command = it.next();
			options.put(command, new SimpleMouseListener() {

				@Override
				public void mouseClicked(MouseEvent e) {
					chooseCommand(command);
					
				}
				
			});
			
		}
		
		final InteractionCommand exitCommand = new InteractionCommand() {

			@Override
			public String getID() {
				return "Exit";
			}

			@Override
			public void execute() {
				Pauser.resume();
				mOverlay.exitInteraction();
				
			} 
			
			public InteractionCommand clone() {
			    throw new RuntimeException();
			}
			
		};
		
		options.put(exitCommand, new SimpleMouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				chooseCommand(exitCommand);
				
			};
		
		});
		
		
		mOverlay.setInteractionOptions(options);
		// SET OVERLAY MESSAGE HERE FROM SPOOLER
		
		mOverlay.startInteraction();
		
		Pauser.pause();
		
		
		
	}

	@Override
	public void reset() {
		// nothing
	}

	
	private void chooseCommand(InteractionCommand command) {
		Pauser.resume();
		
		command.execute();
		
		mOverlay.exitInteraction();
		
	}
	
	private void forceStartInteraction() {
		mOverlay.startInteraction();
	}
	
	private void forceStopInteraction() {
		mOverlay.exitInteraction();
	}

}
